package com.meng.demo1.stresstesting;


import okhttp3.OkHttpClient;

import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 * Description:
 *
 * @Author: menglinggang
 * @Date: 2020-07-22
 * @Time: 下午12:50
 */
public class Test {


    static ExecutorService executorService = Executors.newSingleThreadExecutor();	//创建一个单线程执行器

    public static void main(String[] args) {
        Test test = new Test();
        test.test("http://www.baidu.com", 10, 100);

    }

    public void test(final String url, final int concurrent, int total){


        int runTime = (total + concurrent - 1)/concurrent;

        List<CallResult> results = new ArrayList<>();
        for (int i = 0 ;i< runTime; i ++) {
            Future<List<CallResult>> temp = executorService.submit(new Callable<List<CallResult>>() {
                @Override
                public List<CallResult> call() throws Exception {
                    OkHttpClient okHttpClient = new OkHttpClient();
                    ConcurrentMap<String, CallResult> resultMap = new ConcurrentHashMap<>();
                    CountDownLatch startDownLatch = new CountDownLatch(1);
                    CountDownLatch endDownLatch = new CountDownLatch(concurrent);
                    for (int j=0  ; j< concurrent; j++ ) {
                        Thread task = new Thread(new RunTask(UUID.randomUUID().toString() + "-" + j, url, startDownLatch, endDownLatch, resultMap, okHttpClient));
                        task.start();
                    }
                    startDownLatch.countDown();
                    endDownLatch.await();

                    return new ArrayList<>(resultMap.values());
                }
            });
            try {
                results.addAll(temp.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
        for (CallResult result : results) {
            System.out.println(result);
        }

        System.out.println("平均响应时间 ： " + averageTime(results));
        System.out.println("百分之95响应时间 ： " + percentage95(results));
    }

    private long averageTime(List<CallResult> results){
        if (results == null || results.isEmpty()) {
            return 0;
        }
        long sum = 0;
        for (CallResult result : results) {
            sum = sum + result.getHoldTime();
        }
        return  sum / results.size();
    }

    private long percentage95(List<CallResult> results){
        if (results == null || results.isEmpty()) {
            return 0;
        }
        List<Long> times = new ArrayList<>();
        for (CallResult result : results) {
            times.add(result.getHoldTime());
        }

        times = times.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
        int total = results.size();
        int index = (int)(total * 0.95);

        return times.get(index);

    }


}
